package bancosys.tec.persist.bussobj;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
import javax.persistence.Version;

import jmine.tec.persist.Versioned;
import jmine.tec.persist.annotation.Constraint;
import jmine.tec.persist.annotation.DefaultValue;

import org.hibernate.annotations.Type;

import bancosys.tec.component.Documentation;
import bancosys.tec.persist.audit.Auditable;
import bancosys.tec.persist.authorization.Authorizable;
import bancosys.tec.persist.authorization.AuthorizationMode;
import bancosys.tec.persist.authorization.Authorizer;
import bancosys.tec.persist.authorization.annotation.DisplayName;
import bancosys.tec.persist.persister.PersistenceAction;
import bancosys.tec.utils.date.Timestamp;

/**
 * @author Alexandre
 */
@MappedSuperclass
public abstract class AuthPersistableBusinessObject extends PersistableBusinessObject implements Authorizable, Auditable, Versioned {
    private Long authId = null;

    private PersistenceAction persistenceAction;

    private String user;

    private Timestamp timeStamp;

    private Boolean auth = Boolean.FALSE;

    private Long version;

    /**
     * Version para lock otimista.
     * 
     * @return the version
     */
    @Version
    @Column(name = "VERSION", nullable = false)
    @Documentation("CAMPO PARA LOCK OTIMISTA.")
    public Long getVersion() {
        return this.version;
    }

    /**
     * @param version the version to set
     */
    public void setVersion(Long version) {
        this.version = version;
    }

    /**
     * Retorna se o persistivel está em autorização ou não.
     * 
     * @return <code>true</code> se estiver em autorização, <code>false</code> caso contrário.
     */
    @Constraint(suffix = "JT_0")
    @Column(name = "AUTH", nullable = false)
    @DefaultValue("0")
    @Documentation("CAMPO QUE INDICA SE O REGISTRO ESTA EM AUTORIZACAO (1) OU NÃO (0).")
    public Boolean getAuth() {
        return this.auth;
    }

    /**
     * Define se o persistivel está em autorização ou não.
     * 
     * @param auth <code>true</code> se estiver em autorização, <code>false</code> caso contrário.
     */
    public void setAuth(Boolean auth) {
        this.auth = auth;
    }

    /**
     * Devolve o id de autorização.
     * 
     * @return o id de autorização.
     */
    @Column(name = "COD_AUT")
    @Type(type = "java.lang.Long")
    @Documentation("CODIGO ORIGINAL DO REGISTRO PENDENTE DE AUTORIZACAO. UTILIZADO EM CASO DE ALTERACAO OU EXCLUSAO DO REGISTRO.")
    public Serializable getAuthId() {
        return this.authId;
    }

    /**
     * Define o id de autorização.
     * 
     * @param authId o id de autorização.
     */
    public void setAuthId(Serializable authId) {
        this.authId = (Long) authId;
    }

    /**
     * @return o tipo desse comando. Pode ser uma das contantes INSERT, DELETE ou UPDATE
     */
    @Column(name = "OPERACAO", precision = 10)
    @DisplayName(value = "Evento", order = "1")
    @Documentation("INDICA A OPERACAO QUE FOI COLOCADA EM AUTORIZACAO: INCLUSAO (0), ALTERACAO (1), EXCLUSAO (2), "
            + "INCLUSAO NA BASE FRIA (3), ALTERACAO NA BASE FRIA (4), EXCLUSAO NA BASE FRIA (5), INCLUSAO COM ACAO (6),"
            + " ALTERACAO COM ACAO (7), REJEICAO NA AUTORIZACAO (8).")
    @Constraint(suffix = "4")
    public PersistenceAction getPersistenceAction() {
        return this.persistenceAction;
    }

    /**
     * Seta o tipo do comando.
     * 
     * @param persistenceAction tipo desse comando. Pode ser uma das contantes INSERT, DELETE ou UPDATE
     */
    public void setPersistenceAction(PersistenceAction persistenceAction) {
        this.persistenceAction = persistenceAction;
    }

    /**
     * @return o nome do usuario que executou o comando
     */
    @Column(name = "USU_AUT")
    @DisplayName(value = "Usuário", order = "2")
    @Documentation("NOME DO USUARIO QUE COLOCOU O REGISTRO EM AUTORIZACAO.")
    public String getUser() {
        return this.user;
    }

    /**
     * Seta o usuario.
     * 
     * @param user o nome do usuario que executou o comando
     */
    public void setUser(String user) {
        this.user = user;
    }

    /**
     * @return a data e hora em que esse commando foi criado
     */
    @Type(type = "bancosys.tec.persist.hibernate.type.TimestampType")
    @Column(name = "DT_AUT")
    @DisplayName(value = "Data/Hora", order = "3")
    @Documentation("DATA EM QUE O REGISTRO FOI COLOCADO EM AUTORIZACAO.")
    public Timestamp getTimeStamp() {
        return this.timeStamp;
    }

    /**
     * Seta o timeStamp.
     * 
     * @param timeStamp a data e hora em que esse commando foi criado
     */
    public void setTimeStamp(Timestamp timeStamp) {
        this.timeStamp = timeStamp;
    }

    /**
     * @return authorizer
     */
    @Transient
    public Authorizer<?> getAuthorizer() {
        return (Authorizer<?>) this.getPersister();
    }

    /**
     * {@inheritDoc}
     */
    @Transient
    public AuthorizationMode getAuthorizationMode(Object action) {
        return AuthorizationMode.DEFAULT;
    }
}
